package rpg.personagem;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import rpg.recurso.Alimento;
import rpg.recurso.Armamento;
import rpg.recurso.Cantil;
import rpg.recurso.Recurso;
import rpg.recurso.TipoArmamento;

/**
 * Personagem
 *
 * @author Pedro Sebastian
 * @since 31/01/2013
 * @version 0.1
 */
public class Personagem {

    private String nome;
    private int vida;
    private ArrayList<Recurso> recursos;
    private int ataqueTotal; // Ataque total do personagem (com o uso de armas e eventuais itens).
    private int ataqueReal; // Ataque real do personagem (sem o uso de armas e eventuais itens).
    private int defesaTotal; // Defesa total do personagem (com o uso de armaduras e eventuais itens).
    private int defesaReal; // Defesa real do personagem (sem o uso de armaduras e eventuais itens).
    private int velocidadeTotal; // Velocidade total do personagem (com o uso de armaduras e eventuais itens).
    private int velocidadeReal; // Velocidade real do personagem (sem o uso de armaduras e eventuais itens).
    private int nivel;
    private int experiencia;
    private Armamento arma;
    private Armamento armadura;

    public Personagem() {
    }

    public Personagem(String nome, int ataque, int defesa, int velocidade, int nivel) {
        this.nome = nome;
        setVida(100);
        this.ataqueTotal = ataque + (nivel * 2);
        this.ataqueReal = ataque + (nivel * 2);
        this.defesaTotal = defesa + (nivel * 2);
        this.defesaReal = defesa + (nivel * 2);
        this.velocidadeTotal = velocidade + (nivel * 2);
        this.velocidadeReal = velocidade + (nivel * 2);
        this.nivel = nivel;
        this.recursos = new ArrayList<>();
    }

    public void usarArmadura(Armamento armadura) {
        if (TipoArmamento.Armadura.equals(armadura.getTipo())) {
            this.defesaTotal += armadura.getComplemento();
            this.velocidadeTotal -= armadura.getPeso();
        }
    }

    public void tirarArmadura() {
        this.defesaTotal = this.defesaReal;
        this.velocidadeTotal = this.velocidadeReal;
    }

    public void usarArma(Armamento arma) {
        if (TipoArmamento.Arma.equals(arma.getTipo())) {
            this.ataqueTotal += arma.getComplemento();
        }
    }

    public void tirarArma() {
        this.ataqueTotal = this.ataqueReal;
    }

    public void comer(Alimento alimento) {
        atualizarVida(alimento.getHp());
    }

    public void beber(Cantil c) {
        if (c.getQuantidadeDeLiquido() > 0) {
            atualizarVida(c.getLiquido().getHp());
            this.ataqueTotal += c.getLiquido().getForca();
            this.ataqueReal += c.getLiquido().getForca();
            this.defesaTotal += c.getLiquido().getDefesa();
            this.defesaReal += c.getLiquido().getDefesa();
            c.retirar(1);
        }
    }

    public void dormir() {
        atualizarVida(5);
    }

    public int golpear(int numeroRandom) {
        atualizarVida(-1);
        return this.getAtaqueTotal() * numeroRandom;
    }

    public int fugirCombate(int numeroRandom) {
        atualizarVida(-30);
        return this.getVelocidadeTotal() * numeroRandom;
    }

    public int defender(int numeroRandom) {
        atualizarVida(-1);
        return this.getDefesaTotal() * numeroRandom;
    }

    public void atualizarVida(int vida) {
        if (vida < 0) {
            setVida(getVida() - (-vida));
        } else if (vida > 0) {
            setVida(getVida() + vida);
        }
    }

    public void ganharExperiencia(Personagem c) {
        this.experiencia += 15 * c.nivel;
        ganharNivel();
    }

    private void ganharNivel() {
        int proximoNivel = 75;
        for (int i = 0; i <= this.nivel; i++) {
            proximoNivel += 25;
        }
        if (this.experiencia >= proximoNivel) {
            nivel++;
            this.ataqueTotal += 2;
            this.ataqueReal += 2;
            this.defesaTotal += 2;
            this.defesaReal += 2;
            this.velocidadeTotal += 2;
            this.velocidadeReal += 2;
            this.experiencia = experiencia - proximoNivel;
        }
    }

    public void setVida(int vida) {
        this.vida = vida;
        if (vida > 100) {
            this.vida = 100;
        } else if (vida < 0) {
            this.vida = 0;
        }
        if (this.vida <= 0) {
            System.out.println("O personagem morreu.");
        }
    }

    public int getVida() {
        return vida;
    }

    public ArrayList<Recurso> getRecursos() {
        return recursos;
    }

    public Recurso getRecursos(int indice) {
        try {
            return getRecursos().get(indice);
        } catch (IndexOutOfBoundsException erro) {
            return null;
        }
    }

    public void setRecursos(ArrayList<Recurso> recursos) {
        this.setRecursos(recursos);
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getAtaqueTotal() {
        return ataqueTotal;
    }

    public int getDefesaTotal() {
        return defesaTotal;
    }

    public int getVelocidadeTotal() {
        return velocidadeTotal;
    }

    public int getNivel() {
        return nivel;
    }

    public int getExperiencia() {
        return experiencia;
    }

    public void setTotal(int ataque, int defesa, int velocidade, int vida) {
        setVida(vida);
        this.ataqueTotal = ataque;
        this.ataqueReal = ataque;
        this.defesaTotal = defesa;
        this.defesaReal = defesa;
        this.velocidadeTotal = velocidade;
        this.velocidadeReal = velocidade;
    }

    public Armamento getArma() {
        return arma;
    }

    public void setArma(Armamento arma) {
        this.arma = arma;
    }

    public Armamento getArmadura() {
        return armadura;
    }

    public void setArmadura(Armamento armadura) {
        this.armadura = armadura;
    }

    public void pegar(Recurso r) {
        if (getRecursos().size() < 12) {
            getRecursos().add(r);
        }
    }

    public void usarItem(Recurso recurso) {
        if (recurso instanceof Alimento) {
            Alimento m = (Alimento) recurso;
            comer(m);
            diminuiQuantidade(recurso);
        }
        if (recurso instanceof Armamento) {
            equipar((Armamento) recurso);
        }
        if (recurso instanceof Cantil) {
            Cantil c = (Cantil) recurso;
            beber(c);
        }

    }

    public void diminuiQuantidade(Recurso recurso) {
        recurso.setQuantidade(recurso.getQuantidade() - 1);
        if (recurso.getQuantidade() == 0) {
            for (int i = 0; i < getRecursos().size(); i++) {
                if (recurso == getRecursos().get(i)) {
                    getRecursos().remove(i);
                    break;
                }
            }
        }
    }

    public void equipar(Armamento a) {
        getRecursos().remove(a);
        if (a.getTipo() == TipoArmamento.Arma) {
            pegar(arma);
            arma = a;
            usarArma(arma);
        }
        if (a.getTipo() == TipoArmamento.Armadura) {
            pegar(armadura);
            armadura = a;
            usarArmadura(armadura);
        }
        diminuiQuantidade(a);
        ordenaRecursos();
    }

    private void ordenaRecursos() {
        ArrayList<Recurso> inventarioTemp = new ArrayList<Recurso>();
        inventarioTemp.addAll(getRecursos());
        getRecursos().removeAll(recursos);
        for (int i = 0; i < inventarioTemp.size(); i++) {
            if (inventarioTemp.get(i) != null) {
                getRecursos().add(inventarioTemp.get(i));
            }
        }
    }
}
